package cn.heyige.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.heyige.backend.dto.PromptTemplateDto;
import cn.heyige.backend.entity.PromptTemplateDO;
import cn.heyige.backend.exception.BusinessException;
import cn.heyige.backend.exception.ErrorCode;
import cn.heyige.backend.mapper.PromptTemplateMapper;
import cn.heyige.backend.service.PromptTemplateService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class PromptTemplateServiceImpl extends ServiceImpl<PromptTemplateMapper, PromptTemplateDO> implements PromptTemplateService {

    private final PromptTemplateMapper promptTemplateMapper;

    /**
     * 获取提示词模板列表
     *
     * @param page 分页参数
     * @return 提示词模板列表
     */
    public Page<PromptTemplateDto.TemplateResponse> getPromptTemplates(Page<PromptTemplateDO> page) {
        // 使用MyBatis-Plus的LambdaQueryWrapper构建查询条件
        LambdaQueryWrapper<PromptTemplateDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(PromptTemplateDO::getSort);

        Page<PromptTemplateDO> templates = promptTemplateMapper.selectPage(page, queryWrapper);

        // 转换结果
        Page<PromptTemplateDto.TemplateResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(templates.getRecords().stream().map(this::buildTemplateResponse).collect(Collectors.toList()));
        responsePage.setTotal(templates.getTotal());
        return responsePage;
    }

    /**
     * 根据分类获取提示词模板列表
     *
     * @param category 分类
     * @param page     分页参数
     * @return 提示词模板列表
     */
    public Page<PromptTemplateDto.TemplateResponse> getPromptTemplatesByCategory(String category, Page<PromptTemplateDO> page) {
        // 使用MyBatis-Plus的LambdaQueryWrapper构建查询条件
        LambdaQueryWrapper<PromptTemplateDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplateDO::getCategory, category)
                .orderByAsc(PromptTemplateDO::getSort);

        Page<PromptTemplateDO> templates = promptTemplateMapper.selectPage(page, queryWrapper);

        // 转换结果
        Page<PromptTemplateDto.TemplateResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(templates.getRecords().stream().map(this::buildTemplateResponse).collect(Collectors.toList()));
        responsePage.setTotal(templates.getTotal());
        return responsePage;
    }

    /**
     * 根据标签搜索提示词模板列表
     *
     * @param tags 标签
     * @param page 分页参数
     * @return 提示词模板列表
     */
    public Page<PromptTemplateDto.TemplateResponse> getPromptTemplatesByTags(String tags, Page<PromptTemplateDO> page) {
        // 使用MyBatis-Plus的LambdaQueryWrapper构建查询条件
        LambdaQueryWrapper<PromptTemplateDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(PromptTemplateDO::getSort);

        Page<PromptTemplateDO> templates = promptTemplateMapper.selectPage(page, queryWrapper);

        // 转换结果
        Page<PromptTemplateDto.TemplateResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(templates.getRecords().stream().map(this::buildTemplateResponse).collect(Collectors.toList()));
        responsePage.setTotal(templates.getTotal());
        return responsePage;
    }

    /**
     * 获取用户的提示词模板列表
     *
     * @param userId 用户ID
     * @param page   分页参数
     * @return 提示词模板列表
     */
    public IPage<PromptTemplateDto.TemplateResponse> getUserPromptTemplates(Long userId, Page<PromptTemplateDO> page) {
        LambdaQueryWrapper<PromptTemplateDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(PromptTemplateDO::getCreateTime);
        IPage<PromptTemplateDO> templates = promptTemplateMapper.selectPage(page, queryWrapper);
        // 转换结果
        IPage<PromptTemplateDto.TemplateResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(templates.getRecords().stream().map(this::buildTemplateResponse).collect(Collectors.toList()));
        responsePage.setTotal(templates.getTotal());
        return responsePage;
    }

    /**
     * 获取公共提示词模板列表
     *
     * @param page 分页参数
     * @return 提示词模板列表
     */
    public IPage<PromptTemplateDto.TemplateResponse> getPublicPromptTemplates(Page<PromptTemplateDO> page) {
        LambdaQueryWrapper<PromptTemplateDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(PromptTemplateDO::getSort);

        IPage<PromptTemplateDO> templates = promptTemplateMapper.selectPage(page, queryWrapper);

        // 转换结果
        IPage<PromptTemplateDto.TemplateResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(templates.getRecords().stream().map(this::buildTemplateResponse).collect(Collectors.toList()));
        responsePage.setTotal(templates.getTotal());
        return responsePage;
    }

    /**
     * 获取提示词模板详情
     *
     * @param id 提示词模板ID
     * @return 提示词模板详情
     */
    public PromptTemplateDto.TemplateResponse getPromptTemplate(Long id) {
        LambdaQueryWrapper<PromptTemplateDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplateDO::getId, id);

        PromptTemplateDO template = promptTemplateMapper.selectOne(queryWrapper);
        if (template == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "提示词模板不存在");
        }

        // 增加使用次数
        LambdaUpdateWrapper<PromptTemplateDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(PromptTemplateDO::getId, id).setSql("usage_count = usage_count + 1");
        promptTemplateMapper.update(null, updateWrapper);

        return buildTemplateResponse(template);
    }

    /**
     * 添加提示词模板
     *
     * @param userId  用户ID
     * @param request 添加请求
     * @return 提示词模板详情
     */
    @Transactional
    public PromptTemplateDto.TemplateResponse addPromptTemplate(Long userId, PromptTemplateDto.AddRequest request) {
        PromptTemplateDO template = new PromptTemplateDO();
        template.setTitle(request.getTitle());
        template.setDescription(request.getDescription());
        template.setCategory(request.getCategory());
        template.setContent(request.getContent());
        template.setSort(request.getSortOrder());

        promptTemplateMapper.insert(template);

        log.info("用户 {} 添加提示词模板: {}", userId, template.getTitle());

        return buildTemplateResponse(template);
    }

    /**
     * 更新提示词模板
     *
     * @param id      提示词模板ID
     * @param request 更新请求
     * @return 提示词模板详情
     */
    @Transactional
    public PromptTemplateDto.TemplateResponse updatePromptTemplate(Integer id, PromptTemplateDto.UpdateRequest request) {
        // 检查提示词模板是否存在
        PromptTemplateDO template = promptTemplateMapper.selectOne(new LambdaQueryWrapper<PromptTemplateDO>().eq(PromptTemplateDO::getId, id));
        if (null == template) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "提示词模板不存在");
        }

        // 更新提示词模板
        if (StringUtils.hasText(request.getTitle())) {
            template.setTitle(request.getTitle());
        }
        if (StringUtils.hasText(request.getDescription())) {
            template.setDescription(request.getDescription());
        }
        if (StringUtils.hasText(request.getCategory())) {
            template.setCategory(request.getCategory());
        }
        if (StringUtils.hasText(request.getContent())) {
            template.setContent(request.getContent());
        }
        if (request.getSortOrder() != null) {
            template.setSort(request.getSortOrder());
        }

        promptTemplateMapper.updateById(template);

        log.info("更新提示词模板: {}", template.getTitle());

        return buildTemplateResponse(template);
    }

    /**
     * 删除提示词模板
     *
     * @param id     提示词模板ID
     * @param userId 用户ID
     */
    @Transactional
    public void deletePromptTemplate(Long id, Long userId) {
        // 检查提示词模板是否存在
        LambdaQueryWrapper<PromptTemplateDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplateDO::getId, id);

        PromptTemplateDO template = promptTemplateMapper.selectOne(queryWrapper);
        if (template == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "提示词模板不存在");
        }

        promptTemplateMapper.deleteById(template);

        log.info("用户 {} 删除提示词模板: {}", userId, template.getTitle());
    }

    /**
     * 复制提示词模板
     *
     * @param id     提示词模板ID
     * @param userId 用户ID
     * @return 提示词模板详情
     */
    @Transactional
    public PromptTemplateDto.TemplateResponse copyPromptTemplate(Long id, Long userId) {
        // 检查提示词模板是否存在
        LambdaQueryWrapper<PromptTemplateDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplateDO::getId, id);

        PromptTemplateDO template = promptTemplateMapper.selectOne(queryWrapper);
        if (template == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "提示词模板不存在");
        }

        // 创建新的提示词模板
        PromptTemplateDO newTemplate = new PromptTemplateDO();
        newTemplate.setTitle(template.getTitle() + " - 副本");
        newTemplate.setDescription(template.getDescription());
        newTemplate.setCategory(template.getCategory());
        newTemplate.setContent(template.getContent());
        newTemplate.setSort(template.getSort());

        promptTemplateMapper.insert(newTemplate);

        log.info("用户 {} 复制提示词模板: {}", userId, template.getTitle());

        return buildTemplateResponse(newTemplate);
    }

    /**
     * 构建模板响应
     *
     * @param template 模板实体
     * @return 模板响应
     */
    private PromptTemplateDto.TemplateResponse buildTemplateResponse(PromptTemplateDO template) {
        PromptTemplateDto.TemplateResponse response = new PromptTemplateDto.TemplateResponse();
        response.setId(template.getId());
        response.setTitle(template.getTitle());
        response.setDescription(template.getDescription());
        response.setCategory(template.getCategory());
        response.setContent(template.getContent());
        response.setSortOrder(template.getSort());
        response.setCreateTime(template.getCreateTime());
        response.setUpdateTime(template.getUpdateTime());
        return response;
    }
}